package com.kaibes.core.base.util;

import java.lang.reflect.Field;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.util.HashMap;
import java.util.Map;

/**
 * Created by Administrator on 2016/3/19.
 */
public class ObjectUtils {
    
    @SuppressWarnings("unchecked")
    public static <T>T copyProperties(Object from, Class<T> toClazz) {
        try {
            Object to = toClazz.newInstance();
            return (T) copyProperties(from, to);
        } catch (InstantiationException | IllegalAccessException e) {
            e.printStackTrace();
            return null;
        }
    }
    public static <T>T copyProperties(Object from, T to) {
        if (from==null||to==null) {
            return to;
        }
        
        Class<?> fromClass = from.getClass();
        Class<?> toClass = to.getClass();
        
        Field[] fields = toClass.getDeclaredFields();
        if (fromClass == toClass) {
            for (Field field : fields) {
                field.setAccessible(true);
                try {
                    field.set(to, field.get(from));
                } catch (IllegalArgumentException | IllegalAccessException e) {
                }
            }
        } else {
            for (Field field : fields) {
                field.setAccessible(true);
                
                try {
                    Field temp = fromClass.getDeclaredField(field.getName());
                    temp.setAccessible(true);
                    field.set(to, temp.get(from));
                } catch (NoSuchFieldException | SecurityException | IllegalArgumentException | IllegalAccessException e) {
                }
                
            }
        }
        return to;
    }

    public static void setField(Object obj, Field field, Object value) {
        try {
            field.set(obj, value);
        } catch (IllegalArgumentException | IllegalAccessException e) {
            e.printStackTrace();
        }
    }
    
    @SuppressWarnings({ "unchecked", "rawtypes" })
	public static void setField(Object obj, String fieldName, Object value) throws NoSuchFieldException {
    	if (obj instanceof Map) {
    		Map map = (Map) obj;
    		map.put(fieldName, value);
    		return;
    	}
        try {
            Field field = obj.getClass().getDeclaredField(fieldName);
            field.setAccessible(true);
            field.set(obj, value);
        } catch (SecurityException | IllegalArgumentException | IllegalAccessException e) {
            e.printStackTrace();
        }
    }

    @SuppressWarnings({ "unchecked", "rawtypes" })
    public static <T> T getField(Object obj, String fieldName) throws NoSuchFieldException {
    	if (obj instanceof Map) {
    		Map map = (Map) obj;
    		return (T) map.get(fieldName);
    	}
    	
        try {
            Field field = obj.getClass().getDeclaredField(fieldName);
            field.setAccessible(true);
            return (T) field.get(obj);
        } catch (SecurityException | IllegalArgumentException | IllegalAccessException e) {
            return null;
        }
    }

    public static Object doMethod(Object obj, String methodName) {
        Class<? extends Object> clazz = obj.getClass();
        try {
            Method method = clazz.getMethod(methodName);
            method.setAccessible(true);
            return method.invoke(obj);
        } catch (NoSuchMethodException | SecurityException | IllegalAccessException | IllegalArgumentException
                | InvocationTargetException e) {
            e.printStackTrace();
        }
        return null;
    }

    public static Map<String, Object> toMap(Object obj, String...ignores) {
        if (obj == null) {
            return null;
        }
        Map<String, Object> map = new HashMap<>();
        Field[] fields = obj.getClass().getDeclaredFields();
        for (Field field : fields) {
            for (String ignore:ignores) {
                if (field.getName().equals(ignore)) {
                    continue;
                }
            }
            field.setAccessible(true);
            try {
                map.put(field.getName(), field.get(obj));
            } catch (IllegalArgumentException | IllegalAccessException e) {
                throw new RuntimeException(e);
            }
        }
        return map;
    }
    
    public static Map<String, Object> toMapLine(Object obj, String...ignores) {
        if (obj == null) {
            return null;
        }
        Map<String, Object> map = new HashMap<>();
        Field[] fields = obj.getClass().getDeclaredFields();
        for (Field field : fields) {
            for (String ignore:ignores) {
                if (field.getName().equals(ignore)) {
                    continue;
                }
            }
            field.setAccessible(true);
            try {
                map.put(StringUtils.humpToLine(field.getName()), field.get(obj));
            } catch (IllegalArgumentException | IllegalAccessException e) {
                throw new RuntimeException(e);
            }
        }
        return map;
    }
    
    
}
